package com.palazzisoft.musicrecords.search.util;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopScoreDocCollector;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

import com.palazzisoft.musicrecords.search.model.Disc;

public class Indexer {

	public Analyzer analyzer = null;
	public IndexWriterConfig indexWriterConfig = null;
	public IndexWriter writer = null;
	public Directory dir = null;
	
	public Indexer() throws Exception {
	    boolean create = true;
	    File indexDirFile = new File("/tmp/indexer");
	    if (indexDirFile.exists() && indexDirFile.isDirectory()) {
	       create = false;
	    }
	 
	    this.dir = FSDirectory.open(indexDirFile);
	    this.analyzer = new StandardAnalyzer(Version.LUCENE_4_9);
	    this.indexWriterConfig = new IndexWriterConfig(Version.LUCENE_4_9, analyzer);
	 
	    if (create) {
	       indexWriterConfig.setOpenMode(IndexWriterConfig.OpenMode.CREATE);
	    }	
	}
	
	public void addToIndex(Disc disc) throws IOException {
	    this.writer = new IndexWriter(dir, indexWriterConfig);

		Document doc = new Document();
		
		doc.add(new TextField("name", disc.getName(), Field.Store.YES));
		doc.add(new TextField("bandName", disc.getBand().getName(), Field.Store.YES));
		
		StringBuilder artistNames = new StringBuilder();
		
		for (int i = 0; i < disc.getBand().getArtist().size(); i++) {
			artistNames.append(disc.getBand().getArtist().get(i).getNickName());
			
			if (i != disc.getBand().getArtist().size()) {
				artistNames.append(", ");
			}
		}
		
		doc.add(new TextField("artistNames", artistNames.toString(), Field.Store.YES));
		
		writer.addDocument(doc);	    
	    
	    writer.commit();	    
	    writer.close(true);		
	}
	
	public List<String> executeQuery(String text, String column) throws ParseException, IOException {
		List<String> results = new ArrayList<String>();
		Query parser = new QueryParser(Version.LUCENE_4_9, column, analyzer).parse(text);	
		
	    IndexReader reader = DirectoryReader.open(this.dir);
	    IndexSearcher searcher = new IndexSearcher(reader);	

	    TopScoreDocCollector collector = TopScoreDocCollector.create(100, true);	    
	    searcher.search(parser, collector);
	    
	    ScoreDoc[] hits = collector.topDocs().scoreDocs;
	    
	    for (int i = 0; i < hits.length ; i++) {
	    	Document d = searcher.doc(hits[i].doc);
	    	
	    	StringBuilder result = new StringBuilder();
	    	result.append(d.get("name"));
	    	result.append(d.get("bandName"));
	    	result.append(d.get("artistName"));
	    	
	    	results.add(result.toString());
	    }

	    reader.close();
	    
	    return results;
	}
}
